package com.njbw.design_pattern.struct.proxy.dynamicProxy.jdk;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Proxy;

/**
 * jdk 动态代理
 *
 * @author 黄侯淳
 * @since JDK 1.8
 */
@Slf4j
public class Main {

    public static void main(String[] args) {
        // jdk 提供的动态代理实现，主要是使用 Proxy 类来完成
        // 1、classLoader：被代理类的类加载器
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // 2、interfaces：被代理类实现的接口数组
        Class<?>[] interfaces = new Class[]{DataQuery.class};
        // 3、InvocationHandler：调用处理器，主要是处理被代理类的方法
        // 可以在构建 InvocationHandler 的时候传入被代理类的实例
        CacheInvocationHandler invocationHandler = new CacheInvocationHandler(new DatabaseDataQuery());
        // CacheInvocationHandler invocationHandler = new CacheInvocationHandler();
        // 4、创建代理对象 生成的实例都会实现代理的 interfaces 接口
        DataQuery dataQueryProxy = (DataQuery)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
        // 5、事实上调用 query 方法的时候，实际上是调用的 invocationHandler 的 invoke 方法
        String result = dataQueryProxy.query("key1");
        log.info("result={}", result);
        log.info("--------------------");
        result = dataQueryProxy.query("key1");
        log.info("result={}", result);
        log.info("--------------------");
        result = dataQueryProxy.query("key1");
        log.info("result={}", result);
        log.info("++++++++++++++++++++");

        result = dataQueryProxy.queryAll();
        log.info("result={}", result);
        log.info("--------------------");
        result = dataQueryProxy.queryAll();
        log.info("result={}", result);
        log.info("--------------------");
        result = dataQueryProxy.queryAll();
        log.info("result={}", result);
        log.info("--------------------");
    }
}
